# coding: utf-8

# -------------------------------------------------------------------------------
# Name:         mail_client.py
# Description:  邮件客户端
# Author:       XiangjunZhao
# EMAIL:        2419352654@qq.com
# Date:         2020/8/5 17:26
# -------------------------------------------------------------------------------
import logging
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header

logger = logging.getLogger(__name__)


class MailClient(object):
    """
    邮件客户端
    """

    def __init__(self, host=None, port=465, user=None, password=None, use_ssl=True, from_addr=None):
        """
        初始化邮件客户端
        Args:
            host: 主机地址
            port: 端口
            user: 用户名
            password: 密码
            use_ssl: 是否建立ssl连接
            from_addr: 发件人
        """
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.use_ssl = use_ssl or True
        self.from_addr = from_addr

    def send_text(self, subject='', content='', to_addrs=None):
        """
        发送纯文本格式邮件
        Args:
            subject: 邮件主题
            content: 邮件内容
            to_addrs: 收件人列表

        Returns:

        """
        msg = MIMEText(content, 'plain', 'utf-8')
        msg["From"] = Header(self.from_addr, "utf-8")
        if subject:
            msg['Subject'] = Header(subject, 'utf-8')
        self.send_mail(msg=msg.as_string(), to_addrs=to_addrs)

    def send_html(self, subject='', content='', to_addrs=None):
        """
        发送html格式邮件
        Args:
            subject: 邮件主题
            content: 邮件内容，内容是html格式内容
            to_addrs: 收件人列表

        Returns:

        """
        msg = MIMEText(content, 'html', 'utf-8')
        msg["From"] = Header(self.from_addr, "utf-8")
        if subject:
            msg['Subject'] = Header(subject, 'utf-8')
        self.send_mail(msg=msg.as_string(), to_addrs=to_addrs)

    def send_attach(self, subject='', content='', html='', attachments=None, to_addrs=None):
        """
        发送附件邮件，在发送HTML的同时附加一个纯文本，如果收件人无法查看HTML格式的邮件，就可以自动降级查看纯文本邮件。
        Args:
            subject: 邮件主题
            content: 邮件内容，内容是文本格式内容
            html: 邮件内容，内容是html格式内容
            attachments: 邮件附件列表，格式[{'content':str,'filename':str}]
            to_addrs: 收件人列表

        Returns:

        """
        msg = MIMEMultipart(_subtype='related')
        msg_alternative = MIMEMultipart('alternative')

        msg["From"] = Header(self.from_addr, "utf-8")
        if subject:
            msg['Subject'] = Header(subject, 'utf-8')

        if content:
            # 添加文本内容
            msg_content = MIMEText(content, 'plain', 'utf-8')
            msg_alternative.attach(msg_content)

        if html:
            # 添加html内容
            html_content = MIMEText(html, 'html', 'utf-8')
            msg_alternative.attach(html_content)

        msg.attach(msg_alternative)

        # 添加附件内容
        for attachment in attachments:
            msg_attachment = MIMEText(_text=attachment.get('content'), _subtype='base64', _charset='utf-8')
            msg_attachment['Content-Type'] = 'application/octet-stream'
            msg_attachment['Content-Disposition'] = 'attachment;filename={filename}'.format(
                filename=attachment.get('filename'))
            msg.attach(msg_attachment)

        self.send_mail(msg=msg.as_string(), to_addrs=to_addrs)

    def send_mail(self, msg, to_addrs=None):
        """
        发送邮件
        Args:
            msg: 邮件内容，Message实体转成的字符串
            to_addrs: 收件人列表

        Returns:

        """
        if not to_addrs:
            logger.info('邮件发送失败，收件人不能为空，请指定收件人！！！')
            return
        try:
            smtp_obj = smtplib.SMTP_SSL(host=self.host, port=self.port)
            smtp_obj.login(user=self.user, password=self.password)
            smtp_obj.sendmail(from_addr=self.from_addr, to_addrs=to_addrs, msg=msg)
            smtp_obj.close()
        except smtplib.SMTPException as e:
            logger.error('邮件发送失败，原因：{}'.format(str(e)))
